package com.frame.utils;

import java.io.Serializable;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.lang.StringUtils;

public class DaoSupport {
	
	QueryHelper queryHelper;
	
	public void setQueryHelper(QueryHelper queryHelper) {
		System.out.println(" do this queryHelper 111? ------------------------------- " + queryHelper + " ------- hasValue? ------ " + queryHelper.getDataSource() );
		this.queryHelper = queryHelper;
		System.out.println(" do this queryHelper 222? ------------------------------- " + this.queryHelper.hashCode() + " ------- hasValue? ------ " + this.queryHelper.getDataSource() );

	}
	
	/* 插入操作 */
	public boolean insert(String tableName, Object obj) throws Exception{
		return execute(tableName, obj, false, null);
	}
	
	/* 更新操作 */
	public boolean update(String tableName, Object obj) throws Exception{
		Object idValue = null;
		try{
			idValue = BeanUtils.getProperty(obj, "id");
			if(idValue == null){
				throw new Exception("id's value is NULL where update to "+tableName);
			}
		}catch(Exception e){
			throw new Exception("hava an error when update " + tableName);
		}
		return update(tableName, obj, " id = ? ", idValue);
	} 
	
	public boolean update(String tableName, Object obj,String conditions, Object ... conditionVals) throws Exception{
		return execute(tableName, obj, true, conditions, conditionVals);
	} 
	
	/* 删除操作 byId
	 * @throws Exception */
	public boolean delete(String tableName, Object id ) throws Exception{
		return delete(tableName, " id = ? ", id);
	}
	
	/*
	 * 执行更新、插入操作--这里主要是生成sql语句
	 * @param tableName //表名
	 * @param obj // 对象bean
	 * @param isUpdate // 是否是更新
	 * @param conditions // 更新条件
	 * @param conditionVals // 更新参数
	 * @throws Exception
	 */
	public boolean execute(String tableName, Object obj, boolean isUpdate, String conditions, Object ... conditionVals) throws Exception{
		String excuteMethod = "INSERT";
		if(isUpdate)
			excuteMethod = "UPDATE";
		
		// 如果表名为空，则直接报错���
		if(StringUtils.isBlank(tableName))
			throw new Exception("����Ϊ�գ�");
		
		String sql = null;
		List<Object> params = new ArrayList<Object>();
		
		try{
			// 生成插入或更新语句��ɲ����������
			StringBuffer sqlBuffer = new StringBuffer(excuteMethod);
			sqlBuffer.append(" ");
			sqlBuffer.append(tableName);
			sqlBuffer.append(" SET ");
			
			// 生成pro1=?,pro2=?...的样式，同时设置参数����ʽ��ͬʱ���ò���
			KeyAndParams(obj, sqlBuffer, params);
			
			sql = sqlBuffer.toString().substring(0, sqlBuffer.length()-2);
			
			if(isUpdate){
				sql = sql + " WHERE " + conditions;
				for(Object o : conditionVals){
					params.add(o);
				}
			}
			
		/*	System.out.println("---"+sql);
			for(Object o:params){
				System.out.println("-----"+o);
			}*/
			
			if(params.size() > 0){
				return queryHelper.update(sql, params.toArray())>0;
			}
		} catch(Exception e) {
			throw new Exception("create "+ excuteMethod +" sql error", e);
		}
		return false;
	}

	@SuppressWarnings("unchecked")
	private void KeyAndParams(Object obj, StringBuffer sqlBuffer,
			List<Object> params) throws Exception {
		String field = null;
		Object value = null;
		Map map = BeanUtils.describe(obj);
		Iterator fields = map.keySet().iterator();
		
		while(fields.hasNext()){
			field = (String)fields.next();
			value = PropertyUtils.getProperty(obj, field);
			Class c = PropertyUtils.getPropertyType(obj, field);
			// 对null过滤，但对double不过滤？目的，减少要更新的字段?
			// 或后面的：是类的话，也过滤，直接进行下一次循环��
			if((value == null && c != Double.class) || "class".equalsIgnoreCase(field))
				continue;
			
			sqlBuffer.append(field);
			// 生成插入或更新值ֵ
			sqlBuffer.append(" = ?, ");
			if("_NULL_".equals(value))
				params.add(null);
			else 
				params.add(value);
		}
	}
	
	/* getBeanById  通过id查询 */
	public <T> T getBeanById(String tableName, Class<T> beanClass, Object id) throws Exception{
		return getBeanById(tableName, beanClass, id, false, null, null);
	}
	
	/* getBeanById 通过id查询-使用缓存 */
	public <T> T getBeanById(String tableName, Class<T> beanClass, Object id, Serializable key) throws Exception{
		String cache = "ehcache";
		return getBeanById(tableName, beanClass, id, true, cache, key);
	}
	public <T> T getBeanById(String tableName, Class<T> beanClass, Object id, Boolean useCache, String cache, Serializable key) throws Exception{
		if(StringUtils.isBlank(tableName) || id == null){
			throw new Exception("�������sql���");
		}
		
		StringBuffer sql = new StringBuffer();
		sql.append("SELECT * FROM ");
		sql.append(tableName);
		sql.append(" where id = ? ");
		
		T t = null;
		if(useCache){
			t = queryHelper.read(beanClass, cache, key, sql.toString(), id);
		} else {
			t = queryHelper.read(beanClass, sql.toString(), id);
		}
		return t;
	}
	
	/* getBean by property  通过属性查询 */
	public <T> T getBeanByProperty(String tableName, Class<T> beanClass, String conditions, Object ... conditionVals) throws Exception{
		if(StringUtils.isBlank(tableName) || conditionVals == null){
			throw new Exception("不能生成sql语句");
		}
		
		StringBuffer sql = new StringBuffer();
		sql.append("SELECT * FROM ");
		sql.append(tableName);
		sql.append(" WHERE ");
		sql.append(conditions);
		
		List<Object> params = new ArrayList<Object>();
		for(Object o : conditionVals){
			params.add(o);
		}
		
		if(params.size()>0){
			return (T) queryHelper.read(beanClass, sql.toString(), params.toArray());
		}
		
		return null;
	}
	
	/* 删除操作 */
	public boolean delete(String tableName, String conditions, Object ... conditionVals ) throws Exception{
		if(StringUtils.isBlank(tableName) || StringUtils.isBlank(conditions)){
			throw new Exception("无法生成sql语句");
		}
		try{
			StringBuffer sql = new StringBuffer();
			sql.append("DELETE FROM ");
			sql.append(tableName);
			sql.append(" WHERE ");
			sql.append(conditions);
			
			List<Object> params = new ArrayList<Object>();
			for(Object o : conditionVals){
				params.add(o);
			}
			
			if(params.size() > 0){
				return queryHelper.update(sql.toString(), params.toArray())>0;
			}
		} catch (Exception e) {
			throw new Exception("delete " + tableName + " error ");
		}
		
		return false;
	}
	
	/* 查询列表 
	 * @throws SQLException */
	public <T> List<T> query(Class<T> beanClass, String sql, Object ... params ) throws SQLException{
		return queryHelper.query(beanClass, sql, params);
	}
}
